const jwt = require('jsonwebtoken')
const trash = require('@/utils/ini.util')
const JsonResult = require('@/utils/httpResponse.util')
const awaitSetPermissionMap = require('@/utils/permissionMap.util')
const staffModel = require('@/models/staff.model')
const permissionModel = require('@/models/permission.model')
const auth = () => {
  return async (req, response, next) => {
    try {
      const headers = req.headers
      if (!headers.accesstoken) {
        return JsonResult.httpStatus(req, response, 401, {
          message: 'Authentication failed!',
          code: '9999'
        })
      }
      const decodedToken = jwt.verify(headers.accesstoken, trash.jsonSecretkey)
      const user = await staffModel.findOneById(decodedToken.id)
      if (!user) {
        return JsonResult.httpStatus(req, response, 401, {
          message: 'Authentication failed!',
          code: '9999'
        })
      }
      const permissionMap = await awaitSetPermissionMap()
      const sourceCode = `${req._parsedOriginalUrl.pathname}:${req.method}`
      const permissionCode = permissionMap.get(sourceCode)
      if (permissionCode) {
        const permissionCodes = (await permissionModel.findPermissionByStaffId(decodedToken.id)).map(o => o.code)
        if (!permissionCodes.find(code => code === permissionCode)) {
          return JsonResult.httpStatus(req, response, 403, {
            message: '用户无权限',
            code: '9999'
          })
        }
      }
      req.sessionuser = user
      next()
    } catch (error) {
      return JsonResult.httpStatus(req, response, 401, {
        message: 'Authentication failed!',
        code: '9999'
      })
    }
  }
}

module.exports = auth
